package com.atguigu.lease.common.utils;

import com.atguigu.lease.common.exception.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SignatureException;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * ClassName: JwtUtil
 * Description:
 *  token 的工具类
 * @Author 刘艳丽
 * @Create 2024/9/24 20:25
 * @Version 1.0
 */
public class JwtUtil {

    // 签名(设置一个唯一签名)
    private static SecretKey secretKey = Keys.hmacShaKeyFor("8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92".getBytes());

    // 过期时间: 默认单位: 毫秒
    private static long expireTime = 1000*60*60*24*365l;
    // 创建token
    /**
     * 把登录用户的信息写入到token中
     *  userId 登录用户的唯一标识
     *  account 用户的账号(后台系统的账号: userName  app系统: phone)
     */
    public static String createToken(Long userId, String account){



        // 负载: 设置登录的信息
        Map payload = new HashMap();
        payload.put("userId", userId);
        payload.put("account", account);



        /**
         * 该Java代码生成一个JWT（JSON Web Token）字符串：
         * 设置主题为"user-info"；
         * 设置过期时间为当前时间加上expireTime毫秒；
         * 将payload中的自定义声明数据添加到JWT中；
         * 使用secretKey进行签名；
         * 采用GZIP压缩算法压缩Token信息；
         * 最终生成紧凑格式的JWT字符串。
         */
        String token = Jwts.builder()
                .setSubject("user-info")  // 主题
                .setClaims(payload)  // 设置负载(claims)
                .setExpiration(new Date(System.currentTimeMillis() + expireTime))  // 设置过期时间

                .signWith(secretKey) // 签名
                .compressWith(CompressionCodecs.GZIP) // 压缩token信息
                .compact();  // 生成紧凑格式的JWT字符串
        return token;

    }


    // 解析token
    public static Claims parserToken(String token){
        try {
            // 解析token内容: 必须提供创建token时的签名
            Jws<Claims> claimsJws = Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token);
            // 获取token中的负载数据
            Claims body = claimsJws.getBody();
            return body;
        } catch (ExpiredJwtException e) {
            throw new LeaseException(ResultCodeEnum.TOKEN_EXPIRED);
        } catch (Exception e){
            throw new LeaseException(ResultCodeEnum.TOKEN_INVALID);
        }
    }

    public static void main(String[] args) {
        String token = createToken(1L, "zhangsan");
        System.out.println(token);

        try {
            Thread.sleep(expireTime + 5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
//        Claims claims = parserToken("eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAA_6tWKi1OLfJMUbIy1FFKTE7OL80rUbJSqspIzEsvTsxTqgUAhyLRtyEAAAA.pL_vCRsh8WMefXUT7tkbd582qzpsMK7KndsjxtNb5kkFxWoQQ3d33qulgoo5hn4ZfK2zl9sq1ITUTdCRXzwU7w");

        Claims claims = parserToken(token);
        Long userId = claims.get("userId", Long.class);
        String account = claims.get("account", String.class);

        System.out.println(userId + "," + account);
    }
}
